//! REST API查询处理器
//! 
//! 提供RESTful API查询解析、路由和执行功能

use std::collections::HashMap;
use async_trait::async_trait;
use serde_json::{Value, json};
use anyhow::{Result, anyhow};

/// HTTP方法
#[derive(Debug, Clone, PartialEq)]
pub enum HttpMethod {
    GET,
    POST,
    PUT,
    DELETE,
    PATCH,
    HEAD,
    OPTIONS,
}

impl std::str::FromStr for HttpMethod {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> Result<Self> {
        match s.to_uppercase().as_str() {
            "GET" => Ok(HttpMethod::GET),
            "POST" => Ok(HttpMethod::POST),
            "PUT" => Ok(HttpMethod::PUT),
            "DELETE" => Ok(HttpMethod::DELETE),
            "PATCH" => Ok(HttpMethod::PATCH),
            "HEAD" => Ok(HttpMethod::HEAD),
            "OPTIONS" => Ok(HttpMethod::OPTIONS),
            _ => Err(anyhow!("Unsupported HTTP method: {}", s)),
        }
    }
}

/// REST API请求
#[derive(Debug, Clone)]
pub struct RestRequest {
    /// HTTP方法
    pub method: HttpMethod,
    /// 请求路径
    pub path: String,
    /// 查询参数
    pub query_params: HashMap<String, String>,
    /// 请求头
    pub headers: HashMap<String, String>,
    /// 请求体
    pub body: Option<Value>,
}

/// REST API响应
#[derive(Debug, Clone)]
pub struct RestResponse {
    /// 状态码
    pub status_code: u16,
    /// 响应头
    pub headers: HashMap<String, String>,
    /// 响应体
    pub body: Value,
}

/// REST API路由
#[derive(Debug, Clone)]
pub struct RestRoute {
    /// HTTP方法
    pub method: HttpMethod,
    /// 路径模式
    pub path_pattern: String,
    /// 路径参数
    pub path_params: Vec<String>,
    /// 处理器名称
    pub handler: String,
}

/// REST API路由器
pub struct RestRouter {
    /// 路由列表
    routes: Vec<RestRoute>,
    /// 数据源映射
    data_sources: HashMap<String, Box<dyn RestDataSource>>,
}

/// REST数据源trait
#[async_trait]
pub trait RestDataSource: Send + Sync {
    /// 获取数据源名称
    fn name(&self) -> &str;
    
    /// 处理REST请求
    async fn handle_request(&self, request: &RestRequest, context: &RestContext) -> Result<RestResponse>;
    
    /// 获取支持的路由
    fn get_routes(&self) -> Vec<RestRoute>;
}

/// REST执行上下文
#[derive(Debug, Clone)]
pub struct RestContext {
    /// 路径参数
    pub path_params: HashMap<String, String>,
    /// 用户信息
    pub user_info: HashMap<String, Value>,
    /// 请求元数据
    pub metadata: HashMap<String, Value>,
}

impl RestRouter {
    /// 创建新的REST路由器
    pub fn new() -> Self {
        Self {
            routes: Vec::new(),
            data_sources: HashMap::new(),
        }
    }

    /// 注册数据源
    pub fn register_data_source(&mut self, name: String, data_source: Box<dyn RestDataSource>) {
        // 注册数据源的路由
        let routes = data_source.get_routes();
        for route in routes {
            self.routes.push(route);
        }
        
        self.data_sources.insert(name, data_source);
    }

    /// 处理REST请求
    pub async fn handle_request(&self, request: RestRequest) -> Result<RestResponse> {
        // 查找匹配的路由
        if let Some((route, path_params)) = self.find_matching_route(&request) {
            let context = RestContext {
                path_params,
                user_info: HashMap::new(),
                metadata: HashMap::new(),
            };

            // 根据处理器名称找到对应的数据源
            if let Some(data_source) = self.data_sources.get(&route.handler) {
                data_source.handle_request(&request, &context).await
            } else {
                Ok(RestResponse {
                    status_code: 500,
                    headers: HashMap::new(),
                    body: json!({"error": "Handler not found"}),
                })
            }
        } else {
            Ok(RestResponse {
                status_code: 404,
                headers: HashMap::new(),
                body: json!({"error": "Route not found"}),
            })
        }
    }

    /// 查找匹配的路由
    fn find_matching_route(&self, request: &RestRequest) -> Option<(RestRoute, HashMap<String, String>)> {
        for route in &self.routes {
            if route.method == request.method {
                if let Some(path_params) = self.match_path(&route.path_pattern, &request.path) {
                    return Some((route.clone(), path_params));
                }
            }
        }
        None
    }

    /// 匹配路径
    fn match_path(&self, pattern: &str, path: &str) -> Option<HashMap<String, String>> {
        let pattern_parts: Vec<&str> = pattern.split('/').collect();
        let path_parts: Vec<&str> = path.split('/').collect();

        if pattern_parts.len() != path_parts.len() {
            return None;
        }

        let mut path_params = HashMap::new();

        for (pattern_part, path_part) in pattern_parts.iter().zip(path_parts.iter()) {
            if pattern_part.starts_with('{') && pattern_part.ends_with('}') {
                // 路径参数
                let param_name = &pattern_part[1..pattern_part.len()-1];
                path_params.insert(param_name.to_string(), path_part.to_string());
            } else if pattern_part != path_part {
                // 字面量不匹配
                return None;
            }
        }

        Some(path_params)
    }
}

impl Default for RestRouter {
    fn default() -> Self {
        Self::new()
    }
}

/// 内存数据源的REST适配器
pub struct MemoryRestDataSource {
    /// 数据存储
    data: HashMap<String, Vec<HashMap<String, Value>>>,
}

impl MemoryRestDataSource {
    /// 创建新的内存REST数据源
    pub fn new() -> Self {
        let mut data = HashMap::new();
        
        // 添加示例用户数据
        let users = vec![
            [
                ("id".to_string(), json!(1)),
                ("name".to_string(), json!("张三")),
                ("email".to_string(), json!("zhangsan@example.com")),
                ("age".to_string(), json!(25)),
            ].iter().cloned().collect(),
            [
                ("id".to_string(), json!(2)),
                ("name".to_string(), json!("李四")),
                ("email".to_string(), json!("lisi@example.com")),
                ("age".to_string(), json!(30)),
            ].iter().cloned().collect(),
        ];
        data.insert("users".to_string(), users);
        
        // 添加示例产品数据
        let products = vec![
            [
                ("id".to_string(), json!(1)),
                ("name".to_string(), json!("笔记本电脑")),
                ("price".to_string(), json!(5999.99)),
                ("category".to_string(), json!("电子产品")),
            ].iter().cloned().collect(),
            [
                ("id".to_string(), json!(2)),
                ("name".to_string(), json!("智能手机")),
                ("price".to_string(), json!(2999.99)),
                ("category".to_string(), json!("电子产品")),
            ].iter().cloned().collect(),
        ];
        data.insert("products".to_string(), products);
        
        Self { data }
    }
}

#[async_trait]
impl RestDataSource for MemoryRestDataSource {
    fn name(&self) -> &str {
        "memory"
    }

    async fn handle_request(&self, request: &RestRequest, context: &RestContext) -> Result<RestResponse> {
        match request.method {
            HttpMethod::GET => self.handle_get(request, context).await,
            HttpMethod::POST => self.handle_post(request, context).await,
            HttpMethod::PUT => self.handle_put(request, context).await,
            HttpMethod::DELETE => self.handle_delete(request, context).await,
            _ => Ok(RestResponse {
                status_code: 405,
                headers: HashMap::new(),
                body: json!({"error": "Method not allowed"}),
            }),
        }
    }

    fn get_routes(&self) -> Vec<RestRoute> {
        vec![
            RestRoute {
                method: HttpMethod::GET,
                path_pattern: "/api/users".to_string(),
                path_params: vec![],
                handler: "memory".to_string(),
            },
            RestRoute {
                method: HttpMethod::GET,
                path_pattern: "/api/users/{id}".to_string(),
                path_params: vec!["id".to_string()],
                handler: "memory".to_string(),
            },
            RestRoute {
                method: HttpMethod::POST,
                path_pattern: "/api/users".to_string(),
                path_params: vec![],
                handler: "memory".to_string(),
            },
            RestRoute {
                method: HttpMethod::GET,
                path_pattern: "/api/products".to_string(),
                path_params: vec![],
                handler: "memory".to_string(),
            },
            RestRoute {
                method: HttpMethod::GET,
                path_pattern: "/api/products/{id}".to_string(),
                path_params: vec!["id".to_string()],
                handler: "memory".to_string(),
            },
        ]
    }
}

impl MemoryRestDataSource {
    /// 处理GET请求
    async fn handle_get(&self, request: &RestRequest, context: &RestContext) -> Result<RestResponse> {
        if request.path.starts_with("/api/users") {
            if let Some(id) = context.path_params.get("id") {
                // 获取单个用户
                if let Some(users) = self.data.get("users") {
                    if let Ok(user_id) = id.parse::<i64>() {
                        for user in users {
                            if let Some(uid) = user.get("id") {
                                if uid.as_i64() == Some(user_id) {
                                    return Ok(RestResponse {
                                        status_code: 200,
                                        headers: HashMap::new(),
                                        body: json!(user),
                                    });
                                }
                            }
                        }
                    }
                }
                Ok(RestResponse {
                    status_code: 404,
                    headers: HashMap::new(),
                    body: json!({"error": "User not found"}),
                })
            } else {
                // 获取所有用户
                if let Some(users) = self.data.get("users") {
                    Ok(RestResponse {
                        status_code: 200,
                        headers: HashMap::new(),
                        body: json!(users),
                    })
                } else {
                    Ok(RestResponse {
                        status_code: 200,
                        headers: HashMap::new(),
                        body: json!([]),
                    })
                }
            }
        } else if request.path.starts_with("/api/products") {
            if let Some(id) = context.path_params.get("id") {
                // 获取单个产品
                if let Some(products) = self.data.get("products") {
                    if let Ok(product_id) = id.parse::<i64>() {
                        for product in products {
                            if let Some(pid) = product.get("id") {
                                if pid.as_i64() == Some(product_id) {
                                    return Ok(RestResponse {
                                        status_code: 200,
                                        headers: HashMap::new(),
                                        body: json!(product),
                                    });
                                }
                            }
                        }
                    }
                }
                Ok(RestResponse {
                    status_code: 404,
                    headers: HashMap::new(),
                    body: json!({"error": "Product not found"}),
                })
            } else {
                // 获取所有产品
                if let Some(products) = self.data.get("products") {
                    Ok(RestResponse {
                        status_code: 200,
                        headers: HashMap::new(),
                        body: json!(products),
                    })
                } else {
                    Ok(RestResponse {
                        status_code: 200,
                        headers: HashMap::new(),
                        body: json!([]),
                    })
                }
            }
        } else {
            Ok(RestResponse {
                status_code: 404,
                headers: HashMap::new(),
                body: json!({"error": "Endpoint not found"}),
            })
        }
    }

    /// 处理POST请求
    async fn handle_post(&self, _request: &RestRequest, _context: &RestContext) -> Result<RestResponse> {
        // 简化实现：返回创建成功
        Ok(RestResponse {
            status_code: 201,
            headers: HashMap::new(),
            body: json!({"message": "Created successfully", "id": 999}),
        })
    }

    /// 处理PUT请求
    async fn handle_put(&self, _request: &RestRequest, _context: &RestContext) -> Result<RestResponse> {
        // 简化实现：返回更新成功
        Ok(RestResponse {
            status_code: 200,
            headers: HashMap::new(),
            body: json!({"message": "Updated successfully"}),
        })
    }

    /// 处理DELETE请求
    async fn handle_delete(&self, _request: &RestRequest, _context: &RestContext) -> Result<RestResponse> {
        // 简化实现：返回删除成功
        Ok(RestResponse {
            status_code: 200,
            headers: HashMap::new(),
            body: json!({"message": "Deleted successfully"}),
        })
    }
}

impl Default for MemoryRestDataSource {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_http_method_from_str() {
        assert_eq!("GET".parse::<HttpMethod>().unwrap(), HttpMethod::GET);
        assert_eq!("POST".parse::<HttpMethod>().unwrap(), HttpMethod::POST);
        assert_eq!("PUT".parse::<HttpMethod>().unwrap(), HttpMethod::PUT);
        assert_eq!("DELETE".parse::<HttpMethod>().unwrap(), HttpMethod::DELETE);
        assert!("INVALID".parse::<HttpMethod>().is_err());
    }

    #[test]
    fn test_rest_router_path_matching() {
        let router = RestRouter::new();

        // 测试精确匹配
        let params = router.match_path("/api/users", "/api/users");
        assert!(params.is_some());
        assert!(params.unwrap().is_empty());

        // 测试参数匹配
        let params = router.match_path("/api/users/{id}", "/api/users/123");
        assert!(params.is_some());
        let params = params.unwrap();
        assert_eq!(params.get("id"), Some(&"123".to_string()));

        // 测试不匹配
        let params = router.match_path("/api/users", "/api/products");
        assert!(params.is_none());
    }

    #[tokio::test]
    async fn test_memory_rest_data_source_get_users() {
        let data_source = MemoryRestDataSource::new();
        let request = RestRequest {
            method: HttpMethod::GET,
            path: "/api/users".to_string(),
            query_params: HashMap::new(),
            headers: HashMap::new(),
            body: None,
        };
        let context = RestContext {
            path_params: HashMap::new(),
            user_info: HashMap::new(),
            metadata: HashMap::new(),
        };

        let response = data_source.handle_request(&request, &context).await.unwrap();
        assert_eq!(response.status_code, 200);
        assert!(response.body.is_array());
        let users = response.body.as_array().unwrap();
        assert_eq!(users.len(), 2);
    }

    #[tokio::test]
    async fn test_memory_rest_data_source_get_user_by_id() {
        let data_source = MemoryRestDataSource::new();
        let request = RestRequest {
            method: HttpMethod::GET,
            path: "/api/users/1".to_string(),
            query_params: HashMap::new(),
            headers: HashMap::new(),
            body: None,
        };
        let mut context = RestContext {
            path_params: HashMap::new(),
            user_info: HashMap::new(),
            metadata: HashMap::new(),
        };
        context.path_params.insert("id".to_string(), "1".to_string());

        let response = data_source.handle_request(&request, &context).await.unwrap();
        assert_eq!(response.status_code, 200);
        assert!(response.body.is_object());
        let user = response.body.as_object().unwrap();
        assert_eq!(user.get("id"), Some(&json!(1)));
    }

    #[tokio::test]
    async fn test_memory_rest_data_source_user_not_found() {
        let data_source = MemoryRestDataSource::new();
        let request = RestRequest {
            method: HttpMethod::GET,
            path: "/api/users/999".to_string(),
            query_params: HashMap::new(),
            headers: HashMap::new(),
            body: None,
        };
        let mut context = RestContext {
            path_params: HashMap::new(),
            user_info: HashMap::new(),
            metadata: HashMap::new(),
        };
        context.path_params.insert("id".to_string(), "999".to_string());

        let response = data_source.handle_request(&request, &context).await.unwrap();
        assert_eq!(response.status_code, 404);
    }

    #[tokio::test]
    async fn test_rest_router_end_to_end() {
        let mut router = RestRouter::new();
        let data_source = Box::new(MemoryRestDataSource::new());
        router.register_data_source("memory".to_string(), data_source);

        // 测试获取所有用户
        let request = RestRequest {
            method: HttpMethod::GET,
            path: "/api/users".to_string(),
            query_params: HashMap::new(),
            headers: HashMap::new(),
            body: None,
        };

        let response = router.handle_request(request).await.unwrap();
        assert_eq!(response.status_code, 200);
        assert!(response.body.is_array());

        // 测试获取单个用户
        let request = RestRequest {
            method: HttpMethod::GET,
            path: "/api/users/1".to_string(),
            query_params: HashMap::new(),
            headers: HashMap::new(),
            body: None,
        };

        let response = router.handle_request(request).await.unwrap();
        assert_eq!(response.status_code, 200);
        assert!(response.body.is_object());

        // 测试404
        let request = RestRequest {
            method: HttpMethod::GET,
            path: "/api/nonexistent".to_string(),
            query_params: HashMap::new(),
            headers: HashMap::new(),
            body: None,
        };

        let response = router.handle_request(request).await.unwrap();
        assert_eq!(response.status_code, 404);
    }

    #[tokio::test]
    async fn test_rest_router_post_request() {
        let mut router = RestRouter::new();
        let data_source = Box::new(MemoryRestDataSource::new());
        router.register_data_source("memory".to_string(), data_source);

        let request = RestRequest {
            method: HttpMethod::POST,
            path: "/api/users".to_string(),
            query_params: HashMap::new(),
            headers: HashMap::new(),
            body: Some(json!({"name": "新用户", "email": "new@example.com"})),
        };

        let response = router.handle_request(request).await.unwrap();
        assert_eq!(response.status_code, 201);
        assert!(response.body.get("message").is_some());
    }

    #[test]
    fn test_memory_rest_data_source_routes() {
        let data_source = MemoryRestDataSource::new();
        let routes = data_source.get_routes();

        assert_eq!(routes.len(), 5);

        // 验证用户路由
        let user_routes: Vec<_> = routes.iter()
            .filter(|r| r.path_pattern.contains("users"))
            .collect();
        assert_eq!(user_routes.len(), 3);

        // 验证产品路由
        let product_routes: Vec<_> = routes.iter()
            .filter(|r| r.path_pattern.contains("products"))
            .collect();
        assert_eq!(product_routes.len(), 2);
    }
}
